package org.firefly.tool.file;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.bson.Document;

import com.mongodb.BasicDBObject;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.MapReduceIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.model.Filters;

public class StatisticsData {

	public static void main(String[] args) throws Exception {
		StatisticsData d = new StatisticsData();
		String dbName = "nginx_log";
		String collName = "c_18";
		MongoCollection<Document> coll = MongoUtil.instance.getCollection(dbName, collName);

		// d.count(collName, coll);
		// d.live_user_count(collName, coll);
		// d.live_CacheStatus(collName, coll);
		// d.live_upstream_status(collName, coll);
		// d.live_TimeMax(collName, coll);
		// d.live_Time(collName, coll);
		// d.live_half_hour(collName, coll);
		// d.live_one_minute(collName, coll);
		// d.statisticsUrl(collName, coll);
		// d.live_one_minute_v2(collName, coll);
		d.statisticsV2UserCount(collName, coll);
	}

	/**
	 * 计算总数
	 * 
	 * @param collName
	 * @param coll
	 */
	public void count(String collName, MongoCollection<Document> coll) {
		String dbName = "nginx_log";
		String newNAme = collName + "_count";
		MongoCollection<Document> c = MongoUtil.instance.getCollection(dbName, newNAme);
		// 1. 数据总数
		long count = coll.count();
		System.out.println(collName + "- 总量: " + count);
		// 2. V9 总数
		long v_9 = coll.count(Filters.and(Filters.exists("uid"), Filters.exists("custId")));
		System.out.println(collName + "- V9: " + v_9);
		// 3. V8 总数
		System.out.println(collName + "- V8: " + (count - v_9));

		Document document = new Document();

		document.put("name", "total");
		document.put("count", count);
		c.insertOne(document);

		document = new Document();
		document.put("name", "V9");
		document.put("count", v_9);
		c.insertOne(document);

		document = new Document();
		document.put("name", "V8");
		document.put("count", (count - v_9));
		c.insertOne(document);
	}

	/**
	 * 活跃用户
	 * 
	 * @param coll
	 */
	public void live_user_count(String collName, MongoCollection<Document> coll) {
		String dbName = "nginx_log";
		String newNAme = collName + "_live_user";
		MongoCollection<Document> c = MongoUtil.instance.getCollection(dbName, newNAme);
		Document sub_match = new Document();
		Document sub_group = new Document();
		sub_group.put("_id", "$uid");
		sub_group.put("count", new Document("$sum", 1));

		Document match = new Document("$match", sub_match);
		Document group = new Document("$group", sub_group);

		List<Document> aggregateList = new ArrayList<Document>();
		aggregateList.add(match);
		aggregateList.add(group);
		AggregateIterable<Document> resultset = coll.aggregate(aggregateList);
		MongoCursor<Document> cursor = resultset.iterator();

		try {
			int i = 0;
			List<Document> list = new ArrayList<Document>();
			while (cursor.hasNext()) {
				Document item_doc = cursor.next();
				list.add(item_doc);
				i++;
				if (i == 2000) {
					c.insertMany(list);
					list = new ArrayList<Document>();
					i = 0;
				}
			}
		} finally {
			cursor.close();
		}
	}

	/**
	 * 状态
	 * 
	 * @param coll
	 */
	public void live_upstream_status(String collName, MongoCollection<Document> coll) {
		String dbName = "nginx_log";
		String newNAme = collName + "_upstream_status";
		MongoCollection<Document> c = MongoUtil.instance.getCollection(dbName, newNAme);
		Document sub_match = new Document();
		Document sub_group = new Document();

		Document g = new Document();
		g.put("url", "$url");
		g.put("upstream_cache_status", "$upstream_status");

		sub_group.put("_id", g);

		sub_group.put("count", new Document("$sum", 1));

		Document match = new Document("$match", sub_match);
		Document group = new Document("$group", sub_group);

		List<Document> aggregateList = new ArrayList<Document>();
		aggregateList.add(match);
		aggregateList.add(group);
		AggregateIterable<Document> resultset = coll.aggregate(aggregateList);
		MongoCursor<Document> cursor = resultset.iterator();

		try {
			int i = 0;
			List<Document> list = new ArrayList<Document>();
			while (cursor.hasNext()) {
				Document item_doc = cursor.next();
				list.add(item_doc);
			}
			c.insertMany(list);
		} finally {
			cursor.close();
		}
	}

	/**
	 * 缓存
	 * 
	 * @param coll
	 */
	public void live_CacheStatus(String collName, MongoCollection<Document> coll) {
		String dbName = "nginx_log";
		String newNAme = collName + "_cache_Status";
		MongoCollection<Document> c = MongoUtil.instance.getCollection(dbName, newNAme);
		Document sub_match = new Document();
		Document sub_group = new Document();

		Document g = new Document();
		g.put("url", "$url");
		g.put("upstream_cache_status", "$upstream_cache_status");

		sub_group.put("_id", g);

		sub_group.put("count", new Document("$sum", 1));

		Document match = new Document("$match", sub_match);
		Document group = new Document("$group", sub_group);

		List<Document> aggregateList = new ArrayList<Document>();
		aggregateList.add(match);
		aggregateList.add(group);
		AggregateIterable<Document> resultset = coll.aggregate(aggregateList);
		MongoCursor<Document> cursor = resultset.iterator();

		try {
			int i = 0;
			List<Document> list = new ArrayList<Document>();
			while (cursor.hasNext()) {
				Document item_doc = cursor.next();
				list.add(item_doc);
			}
			c.insertMany(list);
		} finally {
			cursor.close();
		}
	}

	/**
	 * 请求时间最大值
	 * 
	 * @param coll
	 */
	public void live_TimeMax(String collName, MongoCollection<Document> coll) {
		String dbName = "nginx_log";
		String newNAme = collName + "_time_max";
		MongoCollection<Document> c = MongoUtil.instance.getCollection(dbName, newNAme);
		Document sub_match = new Document();
		Document sub_group = new Document();

		Document g = new Document();
		sub_group.put("_id", "$url");

		sub_group.put("max_time", new Document("$max", "$request_time"));

		Document match = new Document("$match", sub_match);
		Document group = new Document("$group", sub_group);

		List<Document> aggregateList = new ArrayList<Document>();
		aggregateList.add(match);
		aggregateList.add(group);
		AggregateIterable<Document> resultset = coll.aggregate(aggregateList);
		MongoCursor<Document> cursor = resultset.iterator();

		try {
			int i = 0;
			List<Document> list = new ArrayList<Document>();
			while (cursor.hasNext()) {
				Document item_doc = cursor.next();
				list.add(item_doc);
			}
			c.insertMany(list);
		} finally {
			cursor.close();
		}
	}

	/**
	 * 请求时间
	 * 
	 * @param coll
	 */
	public void live_Time(String collName, MongoCollection<Document> coll) {
		String dbName = "nginx_log";
		String newNAme = collName + "_time";
		MongoCollection<Document> c = MongoUtil.instance.getCollection(dbName, newNAme);
		Document sub_match = new Document();
		sub_match.put("request_time", new Document("$gt", "0.001"));
		Document sub_group = new Document();

		Document g = new Document();
		sub_group.put("_id", "$url");

		sub_group.put("min_time", new Document("$min", "$request_time"));
		sub_group.put("max_time", new Document("$max", "$request_time"));
		sub_group.put("avg_time", new Document("$avg", "$request_time"));
		Document match = new Document("$match", sub_match);
		Document group = new Document("$group", sub_group);

		List<Document> aggregateList = new ArrayList<Document>();
		aggregateList.add(match);
		aggregateList.add(group);
		AggregateIterable<Document> resultset = coll.aggregate(aggregateList);
		MongoCursor<Document> cursor = resultset.iterator();

		try {
			int i = 0;
			List<Document> list = new ArrayList<Document>();
			while (cursor.hasNext()) {
				Document item_doc = cursor.next();
				list.add(item_doc);
			}
			c.insertMany(list);
		} finally {
			cursor.close();
		}
	}

	/**
	 * 请求时间
	 * 
	 * @param coll
	 * @throws Exception
	 */
	public void live_half_hour(String collName, MongoCollection<Document> coll) throws Exception {
		String dbName = "nginx_log";
		String newNAme = collName + "_half_hour";
		MongoCollection<Document> c = MongoUtil.instance.getCollection(dbName, newNAme);

		String date = "2020-04-18 00:00:00";

		for (int i = 0; i <= 48; i++) {

			String sourceDate = addDateMinut(date, i * 30);
			String afterDate = addDateMinut(date, (i + 1) * 30);
			System.out.println(sourceDate);
			Document d = new Document();
			d.put("date", new Document("$gt", sourceDate).append("$lt", afterDate));
			long count = coll.count(d);
			Document newdDocument = new Document();
			newdDocument.put("_id", sourceDate);
			newdDocument.put("count", count);
			c.insertOne(newdDocument);
		}
	}

	/**
	 * 请求时间
	 * 
	 * @param coll
	 */
	public void live_one_minute(String collName, MongoCollection<Document> coll) {
		String dbName = "nginx_log";
		String newNAme = collName + "_one_minute";
		MongoCollection<Document> c = MongoUtil.instance.getCollection(dbName, newNAme);

		String mapFunction = "function () {" + "    emit({" + "       status: this.date.substr(0,16) " + "        }, "
				+ "     {" + "      status: this.date.substr(0,16), " + "      count: 1, " + "      }); " + "} ";
		String reduceFunction = "function (key, values) {" + "    var result = {" + "        status: '',"
				+ "        count: 0," + "                };" + "   values.forEach(function(val){ "
				+ "            result.status = val.status  ;" + "            result.count += val.count; " + "    }); "
				+ "    return result;" + "}";
		Document d = new Document();
		d.put("date", new Document("$gt", "2020-04-18 19:00:00").append("$lt", "2020-04-18 20:00:00"));
		MapReduceIterable<Document> resultset = coll.mapReduce(mapFunction, reduceFunction).filter(d);

		MongoCursor<Document> cursor = resultset.iterator();

		try {
			int i = 0;
			List<Document> list = new ArrayList<Document>();
			while (cursor.hasNext()) {
				Document item_doc = cursor.next();

				Document dd = (Document) item_doc.get("value");
				Double count = dd.getDouble("count");
				dd.put("qps", count / 60);
				list.add(dd);
			}
			c.insertMany(list);
		} finally {
			cursor.close();
		}

	}

	/**
	 * V2-求时间
	 * 
	 * @param coll
	 */
	public void live_one_minute_v2(String collName, MongoCollection<Document> coll) {
		String dbName = "nginx_log";
		String newNAme = collName + "_one_minute_v2";

		MongoCollection<Document> c = MongoUtil.instance.getCollection(dbName, newNAme);

		String mapFunction = "function () {" + "    emit({" + "       status: this.date.substr(0,16) " + "        }, "
				+ "     {" + "      status: this.date.substr(0,16), " + "      count: 1, " + "      }); " + "} ";
		String reduceFunction = "function (key, values) {" + "    var result = {" + "        status: '',"
				+ "        count: 0," + "                };" + "   values.forEach(function(val){ "
				+ "            result.status = val.status  ;" + "            result.count += val.count; " + "    }); "
				+ "    return result;" + "}";
		Document d = new Document();
		d.put("date", new Document("$gt", "2020-04-18 19:00:00").append("$lt", "2020-04-18 20:00:00"));
		d.put("url", new Document("$regex", "/v2/"));
		MapReduceIterable<Document> resultset = coll.mapReduce(mapFunction, reduceFunction).filter(d);

		MongoCursor<Document> cursor = resultset.iterator();

		try {
			int i = 0;
			List<Document> list = new ArrayList<Document>();
			while (cursor.hasNext()) {
				Document item_doc = cursor.next();

				Document dd = (Document) item_doc.get("value");
				Double count = dd.getDouble("count");
				dd.put("qps", count / 60);
				list.add(dd);
			}
			c.insertMany(list);
		} finally {
			cursor.close();
		}

	}

	public static String addDateMinut(String day, int x) {

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 24小时制

		Date date = null;
		try {
			date = format.parse(day);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		if (date == null)
			return "";
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MINUTE, x);// 24小时制
		date = cal.getTime();
		cal = null;
		return format.format(date);

	}

	public void statisticsUrl(String collectionName, MongoCollection<Document> coll) {
		String dbName = "nginx_log";
		String newNAme = collectionName + "_url";
		MongoCollection<Document> c = MongoUtil.instance.getCollection(dbName, newNAme);
		Document sub_match = new Document();
		Document sub_group = new Document();

		Document g = new Document();
		sub_group.put("_id", "$url");

		sub_group.put("sum", new Document("$sum", 1));

		Document match = new Document("$match", sub_match);
		Document group = new Document("$group", sub_group);

		List<Document> aggregateList = new ArrayList<Document>();
		aggregateList.add(match);
		aggregateList.add(group);
		AggregateIterable<Document> resultset = coll.aggregate(aggregateList);
		MongoCursor<Document> cursor = resultset.iterator();

		try {
			int i = 0;
			List<Document> list = new ArrayList<Document>();
			while (cursor.hasNext()) {
				Document item_doc = cursor.next();
				list.add(item_doc);
			}
			c.insertMany(list);
		} finally {
			cursor.close();
		}
	}

	public void statisticsV2UserCount(String collectionName, MongoCollection<Document> coll) {
		String dbName = "nginx_log";
		String newNAme = collectionName + "_v2_user_count";
		MongoCollection<Document> c = MongoUtil.instance.getCollection(dbName, newNAme);
		Document sub_match = new Document();
		sub_match.put("url", new Document("$regex", "/v2/"));

		Document sub_group = new Document();
		sub_group.put("_id", "$uid");
		sub_group.put("sum", new Document("$sum", 1));

		Document match = new Document("$match", sub_match);
		Document group = new Document("$group", sub_group);

		List<Document> aggregateList = new ArrayList<Document>();
		aggregateList.add(match);
		aggregateList.add(group);
		AggregateIterable<Document> resultset = coll.aggregate(aggregateList);
		MongoCursor<Document> cursor = resultset.iterator();

		try {
			int i = 0;
			List<Document> list = new ArrayList<Document>();
			while (cursor.hasNext()) {
				Document item_doc = cursor.next();
				list.add(item_doc);
			}
			c.insertMany(list);
		} finally {
			cursor.close();
		}
	}
}
